package com.revolsys.util;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
import com.revolsys.collection.map.Maps;
public class PropertyDescriptorCache {
private static Map<Class<?>, Map<String, PropertyDescriptor>> propertyDescriptorByClassAndName = new WeakHashMap<>();
private static Map<Class<?>, Map<String, Method>> propertyWriteMethodByClassAndName = new WeakHashMap<>();
public static void clearCache() {
synchronized (propertyDescriptorByClassAndName) {
propertyDescriptorByClassAndName.clear();
propertyWriteMethodByClassAndName.clear();
}
}
public static PropertyDescriptor getPropertyDescriptor(final Class<?> clazz,
final String propertyName) {
final Map<String, PropertyDescriptor> propertyDescriptors = getPropertyDescriptors(clazz);
return propertyDescriptors.get(propertyName);
}
public static PropertyDescriptor getPropertyDescriptor(final Object object,
final String propertyName) {
if (object == null) {
return null;
} else {
final Class<? extends Object> clazz = object.getClass();
return getPropertyDescriptor(clazz, propertyName);
}
}
protected static Map<String, PropertyDescriptor> getPropertyDescriptors(final Class<?> clazz) {
synchronized (propertyDescriptorByClassAndName) {
Map<String, PropertyDescriptor> propertyDescriptors = propertyDescriptorByClassAndName
.get(clazz);
if (propertyDescriptors == null) {
propertyDescriptors = new HashMap<>();
try {
final BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
for (final PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
final String propertyName = propertyDescriptor.getName();
propertyDescriptors.put(propertyName, propertyDescriptor);
Method writeMethod = propertyDescriptor.getWriteMethod();
if (writeMethod == null) {
final String setMethodName = "set" + Character.toUpperCase(propertyName.charAt(0))
+ propertyName.substring(1);
try {
final Class<?> propertyType = propertyDescriptor.getPropertyType();
writeMethod = clazz.getMethod(setMethodName, propertyType);
propertyDescriptor.setWriteMethod(writeMethod);
} catch (NoSuchMethodException | SecurityException e) {
}
}
Maps.put(propertyWriteMethodByClassAndName, clazz, propertyName, writeMethod);
}
} catch (final IntrospectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
propertyDescriptorByClassAndName.put(clazz, propertyDescriptors);
}
return propertyDescriptors;
}
}
protected static Map<String, Method> getWriteMethods(final Class<?> clazz) {
synchronized (propertyDescriptorByClassAndName) {
Map<String, Method> writeMethods = propertyWriteMethodByClassAndName.get(clazz);
if (writeMethods == null) {
getPropertyDescriptors(clazz);
writeMethods = propertyWriteMethodByClassAndName.get(clazz);
}
return writeMethods;
}
}
}